package ru.urfc.portal.developer_tasks.ejb_tests;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

import javax.ejb.EJB;

import org.hamcrest.CoreMatchers;

import ru.urfc.portal.dao.SpectrId;
import ru.urfc.portal.developer_tasks.BaseTestEjb;
import ru.urfc.portal.model.Branch;
import ru.urfc.portal.model.accounting.Balance;
import ru.urfc.portal.model.accounting.Contragent;
import ru.urfc.portal.model.accounting.UnifiedBalanceOperation;
import ru.urfc.portal.operations.BalanceOperationsAgregator;

public class BalanceOperationsAgregatorTestEjb extends BaseTestEjb {

	@EJB BalanceOperationsAgregator agregator;

	Contragent contragent;
	SpectrId contragentId;
	
	@Override
	protected void setUp() throws Exception {
		contragent = persist(new Contragent());
		contragentId = new SpectrId(contragent.getId(), Branch.SVERD);
	}
	
	public void testGetBalanceOperationsFromDateNullToDateNull() {
		persist(new Balance(contragent, 2000, 10, new BigDecimal(100)));
		persist(new Balance(contragent, 2005, 10, new BigDecimal(200)));
		List<UnifiedBalanceOperation> operations = agregator.getBalanceOperations(contragentId, null, null);
		assertEquals(1, operations.size());
		assertEquals(new BigDecimal(200), operations.get(0).getBalance());
	}

	public void testGetBalanceOperationsFromDateNullToDateExactlyTheLastBalanceDate() {
		persist(new Balance(contragent, 2000, 10, new BigDecimal(100)));
		Balance balance = persist(new Balance(contragent, 2005, 10, new BigDecimal(200)));
		persist(new Balance(contragent, 2010, 10, new BigDecimal(300)));
		List<UnifiedBalanceOperation> operations = agregator.getBalanceOperations(contragentId, null, balance.getDate());
		assertEquals(1, operations.size());
		assertEquals(new BigDecimal(200), operations.get(0).getBalance());
	}
	
	public void testGetBalanceOperationsFromDateNullNoData() {
		List<UnifiedBalanceOperation> operations = agregator.getBalanceOperations(contragentId, null, null);
		assertEquals(0, operations.size());		
	}
	
	public void testGetBalanceOperationsOk() {
		persist(new Balance(contragent, 2000, 10, new BigDecimal(100)));
		Balance balanceFrom = persist(new Balance(contragent, 2005, 10, new BigDecimal(100)));
		Balance balance = persist(new Balance(contragent, 2007, 01, new BigDecimal(100)));
		Balance balanceTo = persist(new Balance(contragent, 2010, 10, new BigDecimal(100)));
		persist(new Balance(contragent, 2015, 10, new BigDecimal(100)));
		List<UnifiedBalanceOperation> operations = agregator.getBalanceOperations(contragentId,
				balanceFrom.getDate(), balanceTo.getDate());
		assertEquals(3, operations.size());
		ArrayList<Date> result = new ArrayList<Date>();
		result.add(operations.get(0).getDate());
		result.add(operations.get(1).getDate());
		result.add(operations.get(2).getDate());
		assertThat(result, CoreMatchers.is(Arrays.asList(
				balanceFrom.getDate(),
				balance.getDate(),
				balanceTo.getDate())));
	}
	
	public void testGetBalanceOperationsFromToEmpty() {
		Balance balance = persist(new Balance(contragent, 2000, 01, new BigDecimal(10000)));
		Balance balanceFrom = new Balance(contragent, 2005, 10, new BigDecimal(100));
		Balance balanceTo = new Balance(contragent, 2010, 10, new BigDecimal(100));
		List<UnifiedBalanceOperation> operations = agregator.getBalanceOperations(contragentId,
				balanceFrom.getDate(), balanceTo.getDate());
		assertEquals(1, operations.size());
		assertEquals(balanceFrom.getDate(), operations.get(0).getDate());
		assertEquals(balance.getAmountWithSign(), operations.get(0).getAmountWithSign());
	}
	
	public void testGetBalanceOperationsDayOfMonthNot1() {
		persist(new Balance(contragent, 2000, 04, new BigDecimal(10000)));
		Date date = new Balance(null, 2000, 04, 2, null).getDate(); 
		List<UnifiedBalanceOperation> operations = agregator.getBalanceOperations(
				contragentId, date, date);
		assertEquals(date, operations.get(0).getDate());		
	}

	public void testCalculateBalanceAtOk() {
		Balance balance = persist(new Balance(contragent, 2000, 01, new BigDecimal(100)));
		Balance calculated = agregator.calculateBalanceAt(contragentId, new Balance(null, 2001, 01, null).getDate());
		assertEquals(balance.getAmountWithSign(), calculated.getAmountWithSign());
	}
	
	public void testCalculateBalanceAtNone() {
		Balance calculated = agregator.calculateBalanceAt(contragentId, new Balance(null, 2001, 01, null).getDate());
		assertEquals(new BigDecimal(0), calculated.getAmountWithSign());
	}
	
}
